#pragma once

#include "../Headers/authr.h"
#include "../Headers/types.h"

#include "../NS/nameserver.h"

#include "ct.rpc.h"

#include <vector>
#include <string>
#include <ctime>

struct ChatEvent {
  enum Enum {
    NoEvent     = 0,
    ServerError = 1,
    Msg         = 2,
    StatusMsg   = 3,
    UpdateUsers = 4
  };
  typedef enum Enum Type;
};

struct MessageType {
  enum Enum {
    log      = 0,
    status   = 1,
    error    = 2,
    incoming = 3,
    outgoing = 4
  };
  typedef enum Enum Type;
};

namespace TOB {
  namespace CT {
    
    struct User {
      std::string status;
      std::string statusmsg;
      std::string name;
    };
    
    struct Message {
      MessageType::Type type;
      std::string       data;
      std::string       user;
      time_t            time;
    };
    
    class Client : AuthRequired {
    private:
      CLIENT*            clnt;
      bool               rpcConnected;
      std::vector<User>  users;
    public:
      Client(TOB::Nameserver::IP nsip, std::string username, std::string password);
      ~Client();
      
      // rpc func
      Code::Type connect();
      Code::Type disconnect();
      Code::Type updateUsers();
      Code::Type sendMessage(std::string& msg);
      Code::Type getEvent(ChatEvent::Type& event);
      Code::Type getMsg(Message& msg);
      
      std::vector<User>& getUsers();
    };
    
    class ClientException {
    public:
      ClientException(std::string error);
      std::string errorMsg;
      Code::Type error;
    };
  }
}
